using System;
using System.IO;
using System.Xml;
using UnityEngine;
using System.Collections.Generic;



class CardReader : ScriptableObject {
	public XmlDocument list1;
	public XmlDocument list2;
	//reads the xml documents in to be used later
	
	public const string CARD_LIST_XML = "src/CardList.xml";
	
	public CardReader(){
		parseLists();
	}
	
	private void parseLists(){
		try {
			//Using factory get an instance of document builder
			list1 = new XmlDocument();
			list2 = new XmlDocument();			

			//parse using builder to get DOM representation of the XML file
			list1.Load(CARD_LIST_XML);
			list2.Load(CARD_LIST_XML);
		}catch(Exception) {
			Debug.Log("Problem parsing card lists.");
		}
	}
	//
	public Deck parseDeck(XmlDocument list, Player user, Player opponent){
		//get the root XmlNode
		List<Card> cardList = new List<Card>();
		XmlNodeList nl = list.GetElementsByTagName("Card");
		if(nl != null && nl.Count > 0) {
			for(int i = 0 ; i < nl.Count;i++) {

				//get the employee XmlNode
				XmlNode info = (XmlNode)nl[i];

				//get the Employee object
				Card card = createCard(info, user, opponent);

				//add it to list
				cardList.Add(card);
			}
		}
		return new Deck(cardList);
	}

	private string getTextValue(XmlNode info, string tagName) {
		string textVal = null;
		XmlNodeList cn = info.ChildNodes;
		List<XmlNode> nl = new List<XmlNode>();
		foreach(XmlNode n in cn){if(n.Name == tagName) nl.Add(n);}
		try{
		if(nl != null && nl.Count > 0) {
			XmlNode el = (XmlNode)nl[0];
			textVal = el.InnerText;
		}
		}
		catch(Exception e){Debug.Log("Cannot find or improper formatting for: " + tagName + " for attribute " + info.InnerText);}

		return textVal;
	}


	/**
	 * Calls getTextValue and returns a int value
	 */
	private int getIntValue(XmlNode ele, string tagName) {
		//in production application you would catch the exception
		string text = getTextValue(ele,tagName);
		if (text != null)
		return Int32.Parse(text);
		else
		return -10;
	}

	private Card createCard(XmlNode info, Player user, Player opponent){
		List<EffectActive> activeList = new List<EffectActive>();
		List<EffectPassive> passiveList = new List<EffectPassive>();
		String name = getTextValue(info,"name");
		int egoCost = getIntValue(info,"egoCost");
		int priority = getIntValue(info,"priority");
		String suit = getTextValue(info,"suit");
		String activeDescription = getTextValue(info,"activeDescription");
		String passiveDescription = getTextValue(info,"passiveDescription");
		if(name == null || egoCost == -10 || priority == -10 || suit == null || passiveDescription == null || (activeDescription == null))
			Debug.Log("For card: " + name);
		
		XmlNodeList cn = info.ChildNodes;
		List<XmlNode> actives = new List<XmlNode>();
		List<XmlNode> passives = new List<XmlNode>();
		foreach(XmlNode n in cn){if(n.Name == "active") actives.Add(n); if(n.Name == "passive") passives.Add(n);}
		
		if(actives != null && actives.Count > 0) {
			for(int i = 0 ; i < actives.Count;i++) {
				XmlNode el = (XmlNode)actives[i];
				String type = getTextValue(el,"type") + "Command";
				String subtype = getTextValue(el,"subType");
				if(subtype == null) subtype = "";
				int magnitude = getIntValue(el,"magnitude");
				
				try{
				//Command activeEffect = (Command)EffectActive.createEffect(type);
					activeList.Add(new EffectActive(type, magnitude, user, opponent, subtype));
				}
				catch(Exception){
					Debug.Log("Class" + type + " not found.");
				}			
			}
		}
		
		if(passives != null && passives.Count > 0) {
			for(int i = 0 ; i < passives.Count;i++) {

				XmlNode el = (XmlNode)passives[i];
				String type = getTextValue(el,"type");
				int magnitude = getIntValue(el,"magnitude");
				
				try{
					//Command activeEffect = (Command)Class.forName(type).newInstance();
					passiveList.Add(new EffectPassive(type, magnitude));
					}
					catch(Exception){
						Debug.Log("Class " + type + "() not found.");
					}	
			}
		}

		//Create a new Employee with the value read from the xml nodes
		Card e = new Card(name, activeDescription, passiveDescription, egoCost, priority, suit, activeList, passiveList);

		return e;
	}	

}
